#include "UseBlade.h"

#include "../CommandManager.h"
#include "../GameObjects/Room.h"
#include "../GameObjects/Character.h"
#include "../GameObjects/Item.h"
#include "../GameObjects/World.h"
#include "../Player.h"

#include "../Components/Vitality.h"
#include "../Components/Blade.h"
#include "../Components/Weapon.h"

#include "../StringHelper.h"
#include "../Random.h"

#include <iostream>

void UseBlade::Init()
{
	CommandManager::getSingleton()->add(std::make_shared<Cut>());
	CommandManager::getSingleton()->add(std::make_shared<Stab>());
}

///////////////////////////////////////
// CUT WITH BLADE
///////////////////////////////////////
Cut::Cut() : Command("cut")
{
}
void Cut::execute(const CharacterPtr &character, const RoomPtr &room, const std::vector<std::string> &args)
{
	if(character->getHeldItem() == false)
	{
		if(character->hasPlayer())
			std::cout << "You're not wielding any blade to cut with!" << std::endl;
		return;
	}

	if(args.empty())
	{
		if(character->getHeldItem()->hasComponent("Blade"))
			character->getHeldItem()->getComponent<Blade>("Blade")->cutAir(character, room);
		else if(character->hasComponent("Blade"))
			character->getComponent<Blade>("Blade")->cutAir(character, room);
		else
			std::cout << "UNHANDLED EXCEPTION!" << std::endl;
		return;
	}

	if(args.size() == 1)
	{
		//Check if we're trying to cut at a character in the room
		for(unsigned int i = 0; i < room->getCharacters().size(); i++)
		{
			if(room->getCharacters()[i]->is(args[0]))
			{
				//Are we trying to hit ourselves?
				if(room->getCharacters()[i]->getName() == character->getName())
				{
					if(character->hasPlayer())
						std::cout << "Let's not do that..." << std::endl;
				}
				//Else we cut at the character
				else
				{
					const CharacterPtr &target = room->getCharacters()[i];
					if(character->getHeldItem()->hasComponent("Blade"))
						character->getHeldItem()->getComponent<Blade>("Blade")->cutTarget(character, target, room);
					else if(character->hasComponent("Blade"))
						character->getComponent<Blade>("Blade")->cutTarget(character, target, room);
					else
						std::cout << "UNHANDLED EXCEPTION!" << std::endl;
					
					int dmg = 0;
					if(character->getHeldItem()->hasComponent("Weapon"))
						dmg = character->getHeldItem()->getComponent<Weapon>("Weapon")->calcDamage(Weapon::CUT);

					if(target->hasComponent("Vitality"))
					{
						Character::BodyPart bodypart = target->getRandomBodypart();
						target->getComponent<Vitality>("Vitality")->damage(target, bodypart, dmg, room);
					}
					else
					{
						if(target->hasPlayer())
							std::cout << "You're unaffected!" << std::endl;
						else
							std::cout << StringHelper::toUpper(target->getIndefiniteArticle()) << " " << target->getName() << " seems unaffected!" << std::endl;
					}
				}
				return;
			}
		}
		if(character->hasPlayer())
			std::cout << "Cut whom?" << std::endl;
	}
	if(character->hasPlayer())
		std::cout << "Cut whom?" << std::endl;
}

///////////////////////////////////////
// STAB WITH BLADE
///////////////////////////////////////
Stab::Stab() : Command("stab")
{
}
void Stab::execute(const CharacterPtr &character, const RoomPtr &room, const std::vector<std::string> &args)
{
	if(character->getHeldItem() == false)
	{
		if(character->hasPlayer())
			std::cout << "You're not wielding any blade to stab with!" << std::endl;
		return;
	}

	if(args.empty())
	{
		if(character->hasPlayer())
			std::cout << "You stab forward through the empty air with your " << character->getHeldItem()->getName() << "!" << std::endl;
		return;
	}

	if(args.size() == 1)
	{
		//Check if we're trying to cut at a character in the room
		for(unsigned int i = 0; i < room->getCharacters().size(); i++)
		{
			if(room->getCharacters()[i]->is(args[0]))
			{
				//Are we trying to hit ourselves?
				if(room->getCharacters()[i]->getName() == character->getName())
				{
					if(character->hasPlayer())
						std::cout << "Let's not do that..." << std::endl;
				}
				//Else we cut at the character
				else
				{
					const CharacterPtr &target = room->getCharacters()[i];

					if(character->hasPlayer())
						std::cout << "You stab " << target->getIndefiniteArticle() << " " << target->getName() << " with your " << character->getHeldItem()->getName() << "!" << std::endl;
					else if(target->hasPlayer())
						std::cout << character->getName() << " stab you with " << character->getHeldItem()->getIndefiniteArticle() << " " << character->getHeldItem()->getName() << "!" << std::endl;
					else
						std::cout << character->getName() << " stab " << target->getIndefiniteArticle() << " "<< target->getName() << " with " << character->getSexAsString() << " " << character->getHeldItem()->getName() << "!" << std::endl;
					
					int dmg = Random::getSingleton()->rand(50) + 10;
					if(target->hasComponent("Vitality"))
					{
						Character::BodyPart bodypart = target->getRandomBodypart();
						target->getComponent<Vitality>("Vitality")->damage(target, bodypart, dmg, room);
						
						if(target->hasPlayer())
							std::cout << "You cry out in pain!" << std::endl;
						else
							std::cout << StringHelper::toUpper(target->getIndefiniteArticle()) << " " << target->getName() << " cries out in pain!" << std::endl;
					}
					else
					{
						if(target->hasPlayer())
							std::cout << "You're unaffected!" << std::endl;
						else
							std::cout << StringHelper::toUpper(target->getIndefiniteArticle()) << " " << target->getName() << " seems unaffected!" << std::endl;
					}
				}
				return;
			}
		}
		if(character->hasPlayer())
			std::cout << "Stab whom?" << std::endl;
	}
}
